/*
 * Copyright 2011 Christoph Ludwig (christoph[at]chludwig.de). All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package de.chludwig.ehumanities.provenance.entities;

import java.io.InputStream;
import java.util.UUID;

import javax.ws.rs.core.MediaType;

import de.chludwig.ehumanities.provenance.jaxb.LogEntryMetadataType;
import de.chludwig.ehumanities.provenance.persistence.LogEntryPO;
import de.chludwig.ehumanities.provenance.utils.CalendarUtil;

/**
 * Log entry of a specific workflow step.
 */
public class LogEntry {

  private LogEntryMetadataType metadata;

  private WorkflowContainer container;
  
  private LogEntryPO entryPO;

  public static LogEntry createNewLogEntry(WorkflowContainer container, UUID entryId) {
    LogEntryMetadataType entryMetadata = new LogEntryMetadataType();
    entryMetadata.setUuid(entryId);
    entryMetadata.setTimestamp(CalendarUtil.getInstance().currentTimestamp());
    entryMetadata.setMediaType(MediaType.TEXT_PLAIN_TYPE);

    LogEntry result = new LogEntry(container, entryMetadata);
    LogEntryPO entryPO = entryPOForContainerAndId(container, entryId);
    entryPO.initialize(result);

    return result;
  }
  
  public static LogEntry existingLogEntry(WorkflowContainer container, UUID entryId) {
    LogEntryPO entryPO = entryPOForContainerAndId(container, entryId);
    LogEntryMetadataType entryMetadata = entryPO.readMetadata();

    return new LogEntry(container, entryMetadata);
  }

  private static LogEntryPO entryPOForContainerAndId(WorkflowContainer container, UUID entryId) {
    UUID containerId = container.getContainerId();
    return new LogEntryPO(containerId, entryId);
  }

  public LogEntry(WorkflowContainer container, LogEntryMetadataType metadata) {
    this.container = container;
    this.metadata = metadata;
  }

  /**
   * @return the metadata
   */
  public LogEntryMetadataType getMetadata() {
    return metadata;
  }

  public UUID getEntryId() {
    return getMetadata().getUuid();
  }

  /**
   * @return the container
   */
  public WorkflowContainer getContainer() {
    return container;
  }

  public InputStream getDataStream() {
    return getEntryPO().getDataStream();
  }

  public void updateData(MediaType mediaType, InputStream dataStream) {
    LogEntryMetadataType entryMetadata = getMetadata();
    entryMetadata.setMediaType(mediaType);
    entryMetadata.setTimestamp(CalendarUtil.getInstance().currentTimestamp());
    
    getEntryPO().updateData(this, dataStream);
  }

  private LogEntryPO getEntryPO() {
    if(entryPO == null) {
      entryPO = entryPOForContainerAndId(getContainer(), getEntryId());
    }
    return entryPO;
  }

}
